import cv2
import tkinter as tk
from PIL import Image, ImageTk

class CameraApp(tk.Frame):
    def __init__(self, window, window_title, video_source=0):
        self.window = window
        self.window.title(window_title)
        self.window.iconbitmap("static/favicon.ico")

        self.video_source = video_source
        self.vid = cv2.VideoCapture(self.video_source)
        self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

        self.canvas = tk.Canvas(self.window, width=self.vid.get(cv2.CAP_PROP_FRAME_WIDTH), height=self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT))
        self.canvas.pack()

        self.btn_snapshot = tk.Button(self.window, text="拍照", width=10, command=self.snapshot, bg="#3b80f9", relief='flat', fg='#ffffff')
        self.btn_snapshot.pack(padx=10, pady=10)

        self.update()
    
    def start(self):
        self.window.mainloop()

    def snapshot(self):
        ret, frame = self.vid.read()
        if ret:
            cv2.imwrite("static/temp/temp.png", cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
            self.release_camera()  # 在拍照后释放摄像头资源

    def release_camera(self):
        if self.vid.isOpened():
            self.vid.release()

    def detect_faces(self, frame):
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = self.face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
        for (x, y, w, h) in faces:
            cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
        return frame

    def update(self):
        ret, frame = self.vid.read()
        if ret:
            frame_with_faces = self.detect_faces(frame)
            self.photo = ImageTk.PhotoImage(image=Image.fromarray(cv2.cvtColor(frame_with_faces, cv2.COLOR_BGR2RGB)))
            self.canvas.create_image(0, 0, image=self.photo, anchor=tk.NW)
        self.window.after(10, self.update)

    def __del__(self):
        self.release_camera()  # 在实例销毁时释放摄像头资源

# 设置你的摄像头索引，通常为0，如果有多个摄像头可以尝试不同的索引
# window = tk.Tk()
# video_source = 0
# app = CameraApp(window, "摄像头拍照", video_source)
# app.start()
